﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ObservableCollectionTests.cs" company="XamlNinja">
//   2011 Richard Griffin and Ollie Riches
// </copyright>
// <summary>
//   Observable collection unit tests - we follow BDD principles, http://dannorth.net/introducing-bdd/
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace WP7Contrib.Collections.Tests
{
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using Microsoft.Silverlight.Testing;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Collections;
    using Models;

    [TestClass]
    public class ObservableCollectionTests : SilverlightTest
    {
        [TestMethod]
        public void ShouldRaiseEventWhenItemAdded()
        {
            // Given we have an observable collection...
            var collection = new ObservableCollection<SimpleModel>();

            // Given we can observe events on the collection...
            NotifyCollectionChangedEventArgs @event = null; 
            collection.CollectionChanged += (sender, args) => { @event = args; };
            
            // Given we can create an item to add...
            var item = new SimpleModel("Thanks for all the fish!", 42);

            // When we add an item to the collection...
            collection.Add(item);

            // Then we expect the event to tell us an item has been added...
            Assert.IsNotNull(@event);
            Assert.IsTrue(@event.Action == NotifyCollectionChangedAction.Add);
            Assert.IsTrue(@event.NewStartingIndex == 0);
        }

        [TestMethod]
        public void ShouldRaiseMultipleEventsWhenRangeOfItemsAdded()
        {
            // Given we have an observable collection...
            var collection = new ObservableCollection<SimpleModel>();

            // Given we can observe events on the collection...
            var events = new List<NotifyCollectionChangedEventArgs>();
            collection.CollectionChanged += (sender, args) => events.Add(args);

            // Given we can create an item to add...
            var items = new List<SimpleModel>
            {
                new SimpleModel("Thanks for all the fish!", 42),
                new SimpleModel("Thanks for all the dogs!", 43),
                new SimpleModel("Thanks for all the dolphins!", 44)
            };

            // When we add the item to the collection...
            collection.AddRange(items);

            // Then we expect the event to tell us an item has been added...
            Assert.IsTrue(@events.Where(e => e.Action == NotifyCollectionChangedAction.Add).Count() == items.Count);
        }

        [TestMethod]
        public void ShouldRaiseEventWhenItemRemoved()
        {
            // Given we have an observable collection...
            var collection = new ObservableCollection<SimpleModel>();

            // Given we can observe events on the collection...
            NotifyCollectionChangedEventArgs @event = null;
            collection.CollectionChanged += (sender, args) => { @event = args; };

            // Given we can create an item to add...
            var item = new SimpleModel("Thanks for all the fish!", 42);

            // Given we add an item to the collection...
            collection.Add(item);

            // When we remove an item from the collection...
            collection.Remove(item);

            // Then we expect the event to tell us an item has been removed...
            Assert.IsNotNull(@event);
            Assert.IsTrue(@event.Action == NotifyCollectionChangedAction.Remove);
            Assert.IsTrue(@event.OldItems.Cast<SimpleModel>().FirstOrDefault() == item);
        }
    }
}
